#include "cache-controler.h"

#include <cryptopp/sha.h>
#include <cryptopp/filters.h>
#include <cryptopp/hex.h>

#include <string>
using namespace CryptoPP;

std::list<std::string> cachecontroler::lockFileList;

cachecontroler::cachecontroler(std::string url)
{	
    CryptoPP::SHA1 sha1;
    std::string source = url;  //This will be randomly generated somehow
    std::string hash = "";
    CryptoPP::StringSource(source, true, new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hash))));
    std::string filename = "./cache/" + hash + ".cache";
    openFileWrite(filename);
    std::cout << "open file: " << filename << std::endl;

    urlhash = hash;
    cachecontroler::insertLockList(hash);
}

cachecontroler::cachecontroler(std::string url, bool write)
{
    CryptoPP::SHA1 sha1;
    std::string source = url;  //This will be randomly generated somehow
    std::string hash = "";
    CryptoPP::StringSource(source, true, new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hash))));
    std::string filename = "./cache/" + hash + ".cache";
    if( write ) {
        openFileWrite(filename);
        std::cout << "open file: " << filename << std::endl;
    } else {
        openFileRead(filename);
    }

    urlhash = hash;
    cachecontroler::insertLockList(hash);
}

std::string cachecontroler::hashFilePathUtilities(std::string url) {
    CryptoPP::SHA1 sha1;
    std::string source = url;  //This will be randomly generated somehow
    std::string hash = "";
    CryptoPP::StringSource(source, true, new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hash))));
    std::string filename = "./cache/" + hash + ".cache";

    return filename;
}

std::string cachecontroler::hashURLUtilities(std::string url) {
    CryptoPP::SHA1 sha1;
    std::string source = url;  //This will be randomly generated somehow
    std::string hash = "";
    CryptoPP::StringSource(source, true, new CryptoPP::HashFilter(sha1, new CryptoPP::HexEncoder(new CryptoPP::StringSink(hash))));

    return hash;
}

cachecontroler::~cachecontroler(void)
{
    closeFile();
    cachecontroler::removeLockList(urlhash);
}

void cachecontroler::writeToFile(std::string data) {
    ocachefile << data;
}

//==========list lock function==========
void cachecontroler::insertLockList(std::string filename) {
    cachecontroler::lockFileList.push_back(filename);
}

void cachecontroler::removeLockList(std::string filename) {
    cachecontroler::lockFileList.remove(filename);
}

bool cachecontroler::findLockList(std::string filename) {
    for (std::list<std::string>::iterator it = cachecontroler::lockFileList.begin(); it != cachecontroler::lockFileList.end(); it++) {
        if( *it == filename )
            return true;
    }

    return false;
}

void cachecontroler::printLockList() {
    std::cout << "=========LOCK LIST===========" << std::endl;
    for (std::list<std::string>::iterator it = lockFileList.begin(); it != lockFileList.end(); it++) {
        std::cout << *it << std::endl;
    }
}
